home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Chans / dr2rfc / dr2rfc.c next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  10.7 KB  |  484 lines

  1. /* dr2rfc.c - The PP DR structure to an RFC message */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Chans/dr2rfc/RCS/dr2rfc.c,v 6.0 1991/12/18 20:06:58 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Chans/dr2rfc/RCS/dr2rfc.c,v 6.0 1991/12/18 20:06:58 jpo Rel $
  9.  *
  10.  * $Log: dr2rfc.c,v $
  11.  * Revision 6.0  1991/12/18  20:06:58  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. /****************************************************************************\
  19. *                                                                            *
  20. *  The following checks are done:                                            *
  21. *       -  The message should not as yet be delivered.                       *
  22. *       -  The Recipient number has a DR associated with it.                 *
  23. *       -  All specified recipients have the same DR number.                 *
  24. *                                                                            *
  25. \****************************************************************************/
  26.  
  27.  
  28.  
  29.  
  30. #include <sys/param.h>
  31. #include "head.h"
  32. #include "prm.h"
  33. #include "qmgr.h"
  34. #include "q.h"
  35. #include "tb_a.h"
  36. #include "ap.h"
  37.  
  38. extern  char                            *quedfldir;
  39. extern void    rd_end(), chan_init(), err_abrt(), or_myinit();
  40.  
  41. /* -- static variables -- */
  42. static Q_struct                         Qstruct;
  43. Q_struct                                *PPQuePtr = &Qstruct;
  44. static struct prm_vars                  PRMstruct;
  45. static int                              DRno = 0;
  46. char                                    *this_msg = NULLCP;
  47. int                    order_pref;
  48. int                    io_running;
  49. int                    linked = TRUE;
  50. extern    int                ap_outtype;
  51. static int initproc ();
  52. static int endfunc();
  53. static void dirinit ();
  54. static struct type_Qmgr_DeliveryStatus *process ();
  55. static int adr_checks ();
  56. static int Deliver ();
  57. static void display_ProcMsg ();
  58. char    error[BUFSIZ];
  59. /* -- used by other files -- */
  60. CHAN                                    *mychan;
  61.  
  62. #define    DEFAULT_MAX_INCLUDE    5000
  63. #define DEFAULT_NUM_INCLUDE_LINES    10
  64.     
  65. long    max_include_msg = DEFAULT_MAX_INCLUDE;
  66. int    num_include_lines = DEFAULT_NUM_INCLUDE_LINES;
  67. int    include_all = FALSE;
  68. int    include_admin = FALSE;
  69.  
  70. /* ---------------------  Begin  Routines  -------------------------------- */
  71.  
  72.  
  73.  
  74.  
  75. main (argc, argv)
  76. int     argc;
  77. char    **argv;
  78. {
  79.     char            *myname = argv[0];
  80.  
  81.     if (*myname == '/') {
  82.         myname = rindex (myname, '/');
  83.         myname++;
  84.     }
  85.  
  86.     /* -- read pp tailor file -- */
  87.     chan_init (myname);
  88.  
  89.     /* -- needed for oid_table -- */
  90.     dsap_init ((char ***) NULL, (int *) NULL);
  91.  
  92.     /* -- check that the Q dirs are ok -- */
  93.     dirinit();
  94.  
  95. #ifdef PP_DEBUG
  96.     if (argc > 1 && strcmp (argv[1], "debug") == 0)
  97.            debug_channel_control (argc, argv, initproc, process, endfunc);
  98.     else
  99. #endif
  100.            channel_control (argc, argv, initproc, process, endfunc);
  101.  
  102.  
  103.     exit (0);
  104. }
  105.  
  106.  
  107.  
  108.  
  109. /* ---------------------  Static  Routines  ------------------------------- */
  110.  
  111.  
  112.  
  113.  
  114. static void dirinit()   /* -- Change into pp queue space -- */
  115. {
  116.     PP_TRACE (("dirinit()"));
  117.     if (chdir (quedfldir) < 0)
  118.         err_abrt (RP_LIO, "Unable to change to dir '%s'", quedfldir);
  119. }
  120.  
  121. static void do_ch_info_flags(info)
  122. char    *info;
  123. {
  124.     char    *info_copy, *margv[20];
  125.     int    margc, ix;
  126.  
  127.     if (info == NULLCP) return;
  128.  
  129.     info_copy = strdup(info);
  130.     if ((margc = sstr2arg(info_copy, 20, margv, "= \t,")) > 0) {
  131.         for (ix = 0; ix < margc; ix++) {
  132.             if (lexequ(margv[ix], "order") == 0) {
  133.                 if (lexequ(margv[ix+1], "uk") == 0) {
  134.                     order_pref = CH_UK_PREF;
  135.                     ap_outtype |= AP_PARSE_BIG;
  136.                 }
  137.                 ix ++;
  138.             } else if (lexequ(margv[ix], "submit") == 0) {
  139.                 if (lexequ(margv[ix+1], "linked") == 0)
  140.                     linked = TRUE;
  141.                 else if (lexequ(margv[ix+1], "copy") == 0)
  142.                     linked = FALSE;
  143.                 ix ++;
  144.             } else if (lexequ(margv[ix], "admininfo") == 0) {
  145.                 if (lexequ(margv[ix+1], "true") == 0)
  146.                     include_admin = TRUE;
  147.                 else if (lexequ(margv[ix+1], "false") == 0)
  148.                     include_admin = FALSE;
  149.                 ix++;
  150.             } else if (lexequ(margv[ix], "return") == 0) {
  151.                 if (lexequ(margv[ix+1], "all") == 0) 
  152.                     include_all = TRUE;
  153.                 else {
  154.                     /* number letter */
  155.                     char    *ich = margv[ix+1];
  156.                     
  157.                     while (isdigit(*ich)) ich++;
  158.                     
  159.                     switch (*ich) {
  160.                         case 'l':
  161.                         case 'L':
  162.                         if (*ich == margv[ix+1][0])
  163.                             num_include_lines = 1;
  164.                         else
  165.                             num_include_lines = 
  166.                                 atoi(margv[ix+1]);
  167.                         break;
  168.                         
  169.                         case 'K':
  170.                         case 'k':
  171.                         if (*ich == margv[ix+1][0])
  172.                             max_include_msg = (long) 1000;
  173.                         else
  174.                             max_include_msg =
  175.                                 (long) atoi(margv[ix+1]) * (long) 1000;
  176.                         break;
  177.                         
  178.                         default:
  179.                         PP_LOG(LLOG_EXCEPTIONS,
  180.                                ("Unable to parse LHS as numberletter '%s=%s'", margv[ix], margv[ix+1]));
  181.                     }
  182.                 }
  183.                 ix++;
  184.             } else 
  185.                 PP_LOG(LLOG_EXCEPTIONS,
  186.                        ("Unknown info flag '%s'",
  187.                     margv[ix]));
  188.         }
  189.     }
  190.     free(info_copy);
  191. }
  192.  
  193. static int initproc (arg)
  194. struct type_Qmgr_Channel        *arg;
  195. {
  196.     char                    *myname = qb2str (arg);
  197.     RP_Buf  rps, *rp = &rps;
  198.  
  199.     PP_TRACE (("initproc (%s)", myname));
  200.  
  201.     if ((mychan = ch_nm2struct (myname)) == NULLCHAN)
  202.         err_abrt (RP_PARM, "Channel '%s' not known", myname);
  203.  
  204.     
  205.     /* -- other initialisations -- */
  206.     order_pref = CH_USA_PREF;
  207.     ap_outtype = AP_PARSE_SAME;
  208.     linked = TRUE;
  209.     max_include_msg = DEFAULT_MAX_INCLUDE;
  210.     num_include_lines = DEFAULT_NUM_INCLUDE_LINES;
  211.     include_all = FALSE;
  212.     include_admin = FALSE;
  213.  
  214.     if (mychan->ch_out_info != NULLCP)
  215.         do_ch_info_flags(mychan->ch_out_info);
  216.     
  217.     pp_setuserid();
  218.  
  219.     or_myinit();
  220.  
  221.     if (rp_isbad (io_init(rp)))
  222.         err_abrt (RP_PARM, "io_init err %s", rp -> rp_line);
  223.     else
  224.         io_running = TRUE;
  225.  
  226.     PP_NOTICE (("Channel %s initialised", myname));
  227.     free (myname);
  228.     q_init (PPQuePtr);
  229.     prm_init (&PRMstruct);
  230.     return OK;
  231. }
  232.  
  233. /* ARGSUSED */
  234. static int endfunc (arg)
  235. struct type_Qmgr_Channel *arg;
  236. {
  237.     if (io_running == TRUE)
  238.         io_end(OK);
  239.     io_running = FALSE;
  240. }
  241.  
  242. stop_io()
  243. {
  244.     if (io_running == TRUE)
  245.         io_end(NOTOK);
  246.     io_running = FALSE;
  247. }
  248.  
  249. static struct type_Qmgr_DeliveryStatus *process (arg)
  250. struct type_Qmgr_ProcMsg                *arg;
  251. {
  252.  
  253.     struct type_Qmgr_UserList       *up;
  254.     ADDR                            *ad_list        = NULLADDR,
  255.                     *ad_sender      = NULLADDR,
  256.                     *ad_recip       = NULLADDR,
  257.                     *alp            = NULLADDR,
  258.                     *ap             = NULLADDR;
  259.     int                             naddrs          = 0,
  260.                     ad_count,
  261.                     retval;
  262.  
  263.     if (this_msg)
  264.         free (this_msg);
  265.  
  266.     this_msg = qb2str (arg->qid);
  267.     PP_TRACE (("process (msg = '%s')", this_msg));
  268.     (void) delivery_init (arg->users);
  269.     (void) delivery_setall (int_Qmgr_status_messageFailure);
  270.  
  271. #ifdef PP_DEBUG
  272.     display_ProcMsg (arg);
  273. #endif
  274.  
  275.  
  276.     /* -- Initialisation --*/
  277.  
  278.     DRno = 0;
  279.     q_init (PPQuePtr);
  280.     prm_init (&PRMstruct);
  281.  
  282.  
  283.     /* -- read the addr control file -- */
  284.  
  285.     retval = rd_msg (this_msg, &PRMstruct, PPQuePtr,
  286.             &ad_sender, &ad_recip, &ad_count);
  287.  
  288.     if (rp_isbad (retval)) {
  289.         rd_end();
  290.         PP_LOG (LLOG_EXCEPTIONS, ("rd_msg error: %s", this_msg));
  291.         return delivery_setallstate (int_Qmgr_status_messageFailure,
  292.                          "Can't read message");
  293.     }
  294.  
  295.  
  296.  
  297.     /* -- create a new recip list + perform addr check -- */
  298.  
  299.     for (ap = ad_recip; ap; ap = ap -> ad_next) {
  300.         for (up = arg->users; up; up = up->next) {
  301.             if (up -> RecipientId -> parm != ap -> ad_no)
  302.                 continue;
  303.  
  304.             if (adr_checks (ap) != OK)
  305.                 break;
  306.  
  307.             if (ad_list == NULLADDR)
  308.                 ad_list = alp =
  309.                     (ADDR *) calloc(1, sizeof *alp);
  310.             else {
  311.                 alp -> ad_next =
  312.                     (ADDR *) calloc(1, sizeof *alp);
  313.                 alp = alp -> ad_next;
  314.             }
  315.  
  316.             /* -- struct copy -- */
  317.             *alp = *ap;
  318.             alp -> ad_next = NULLADDR;
  319.             naddrs++;
  320.             break;
  321.         }
  322.     }
  323.  
  324.  
  325.     if (naddrs == 0) {
  326.         PP_LOG (LLOG_EXCEPTIONS, ("No recipients in the user list"));
  327.         rd_end ();
  328.         return deliverystate;
  329.     }
  330.  
  331.  
  332.     /* -- deliverystate set in deliver -- */
  333.     if (Deliver (ad_sender, ad_list) != RP_OK)
  334.         PP_LOG (LLOG_EXCEPTIONS, ("resubmission failed"));
  335.     rd_end();
  336.  
  337.     /* -- free ad_list -- */
  338.     for (alp = ad_list; alp; alp = ap) {
  339.         ap = alp -> ad_next;
  340.         free ((char *)alp);
  341.     }
  342.  
  343.     q_free (PPQuePtr);
  344.     prm_free (&PRMstruct);
  345.  
  346.     return deliverystate;
  347. }
  348.  
  349.  
  350.  
  351.  
  352. static int adr_checks (ap)
  353. ADDR    *ap;
  354. {
  355.     PP_TRACE (("adr_checks (%s)", ap->ad_value));
  356.  
  357.     switch (ap->ad_status) {
  358.         case AD_STAT_DRWRITTEN:
  359.         break;
  360.         case AD_STAT_DONE:
  361.         (void) delivery_set(ap->ad_no,
  362.                     int_Qmgr_status_success);
  363.         return NOTOK;
  364.         default:
  365.         PP_LOG (LLOG_EXCEPTIONS, ("adr_checks - wrong status"));
  366.         (void) delivery_setstate(ap->ad_no,
  367.                     int_Qmgr_status_messageFailure,
  368.                     "adr_checks - wrong status");
  369.            return NOTOK;
  370.     }
  371.  
  372.     if (ap -> ad_resp == 0) {
  373.         PP_LOG (LLOG_EXCEPTIONS,
  374.             ("responsibility bit not set for addr %d",
  375.              ap -> ad_no));
  376.         (void) delivery_setstate (ap -> ad_no,
  377.                      int_Qmgr_status_messageFailure,
  378.                      "responsibility bit not set for addr");
  379.         return NOTOK;
  380.     }
  381.  
  382.  
  383.     if (DRno == 0)
  384.         DRno = ap->ad_no;
  385.     return OK;
  386. }
  387.  
  388.  
  389.  
  390.  
  391. static int Deliver (orig, recip)
  392. ADDR    *orig;
  393. ADDR    *recip;
  394. {
  395.     int     retval = RP_BAD;
  396.     int     value = int_Qmgr_status_messageFailure;
  397.     ADDR    *ap;
  398.     RP_Buf    rps, *rp = &rps;
  399.     PP_TRACE (("Deliver (%s)", orig->ad_value));
  400.     error[0] = '\0';
  401.     if (orig->ad_outchan &&
  402.         orig->ad_outchan->li_chan &&
  403.         orig->ad_outchan->li_chan->ch_name &&
  404.         lexequ(orig->ad_outchan->li_chan->ch_name, mychan->ch_name) == 0) {
  405.            
  406.         if (io_running == FALSE)
  407.             if (rp_isbad(io_init(rp))) {
  408.                 PP_LOG(LLOG_EXCEPTIONS,
  409.                        ("io_init err %s", rp -> rp_line));
  410.                 (void) sprintf (error,
  411.                         "io_init error [%s]",
  412.                         rp -> rp_line);
  413.                 goto Deliver_free;
  414.             } else
  415.                 io_running = TRUE;
  416.             
  417.         if (rp_isbad (write_queue (orig)))
  418.             goto Deliver_free;
  419.  
  420.         if (rp_isbad (write_report (orig, DRno, recip)))
  421.             goto Deliver_free;
  422.  
  423.  
  424.         value = int_Qmgr_status_success;
  425.         retval = RP_OK;
  426.     } else {
  427.         PP_LOG(LLOG_EXCEPTIONS,
  428.                ("Illegal setting of outbound channel for addr %d",
  429.             orig->ad_no));
  430.         (void) sprintf (error,
  431.                 "Illegal setting of outbound channel");
  432.     }
  433.  
  434.     Deliver_free: ;
  435.     for (ap = recip; ap; ap = ap -> ad_next) {
  436.         if (ap -> ad_resp) {
  437.             (void) delivery_setstate (ap -> ad_no, value, error);
  438.             if (value == int_Qmgr_status_success)
  439.                 wr_ad_status (ap, AD_STAT_DONE);
  440.         }
  441.  
  442.     }
  443.  
  444.     if (retval == RP_OK) {
  445.         PP_NOTICE (("Wrote DR to  '%s'", orig->ad_value));
  446.         PP_NOTICE ((">>> %s %s done", mychan -> ch_name, this_msg));
  447.     }
  448.     else {
  449.         PP_OPER (NULLCP, ("dr2rfc has failed for %s", this_msg));
  450.         PP_NOTICE ((">>> %s %s has not been done",
  451.                 mychan -> ch_name, this_msg));
  452.         stop_io ();
  453.     }
  454.  
  455.     return retval;
  456. }
  457.  
  458.  
  459.  
  460.  
  461. /*  --------------------  Debug Proceedures  ------------------------------ */
  462.  
  463.  
  464.  
  465.  
  466. #ifdef PP_DEBUG
  467. static void display_ProcMsg (pm)
  468. struct type_Qmgr_ProcMsg        *pm;
  469. {
  470.     char                    *str;
  471.     struct type_Qmgr_UserList *pmu;
  472.  
  473.     str = qb2str (pm -> qid);
  474.  
  475.     for (pmu = pm -> users; pmu; pmu = pmu -> next)
  476.         PP_TRACE (("%s:  user(%d)",
  477.             str, pmu -> RecipientId->parm));
  478.  
  479.     if (str) free (str);
  480.  
  481.     return;
  482. }
  483. #endif
  484.